From 803255dd6984f210247dee3473604718c2bf4dae Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Tue, 27 Sep 2005 18:23:57 +0000 Subject: [PATCH] added fish time usage profiling --- ChangeLog | 17 +++++++++++++++ babl/babl-classes.h | 49 ++++++++++++++++++++---------------------- babl/babl-fish-path.c | 17 +++++++++------ babl/babl-fish-stats.c | 40 ++++++++++++++++++++++++++++++++++ babl/babl-internal.c | 12 +++++++++-- babl/babl-introspect.c | 7 +++--- babl/babl-util.c | 2 +- extensions/gggl.c | 14 ++++++++---- 8 files changed, 116 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5b76b3..ffc0285 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-09-27 Øyvind Kolås + + * babl/babl-classes.h: Added time consumption instrumentation to + BablFish. + * babl/babl-fish-path.c: (babl_fish_path), (babl_fish_path_process): + intialization of instrumentation data. + * babl/babl-fish-stats.c: (table_destination_each), (each_conv), + (conversions), (babl_fish_stats): Output timing data, as well as a + list of all conversions with the obviously bad ones marked in red. + * babl/babl-internal.c: (babl_process): update instrumentation. + * babl/babl-introspect.c: (conversion_introspect): only query error + from conversions where that is legal. + * babl/babl-util.c: changed from msecs to nsecs (might be some more + places in the code to change names of variables.) + * extensions/gggl.c: (conv_gF_gaF), (conv_gF_rgbF), (conv_rgbF_gF), + (conv_rgbaF_rgb8): Changes to increase sanity. + 2005-09-27 Øyvind Kolås * tests/srgb_to_lab_u8.c: (test): renamed format (srgb -> R'G'B' u8) diff --git a/babl/babl-classes.h b/babl/babl-classes.h index e7ab444..63ed19e 100644 --- a/babl/babl-classes.h +++ b/babl/babl-classes.h @@ -189,21 +189,20 @@ typedef struct int *stride; } BablImage; -/* BablFish base class, the user of babl is just requesting a - * conversion, after that an appropriate species of fish is - * constructed to handle the request. - * - * TODO: - * * implement +/* BablFish, common base class for various fishes. */ typedef struct { BablInstance instance; union Babl *source; union Babl *destination; - int processings; - long pixels; - double error; + + double error; /* the amount of noise introduced by the fish */ + + /* instrumentation */ + int processings; /* number of times the fish has been used */ + long pixels; /* number of pixels translates */ + long msecs; /* msecs spent within this fish */ } BablFish; @@ -211,6 +210,8 @@ typedef struct /* BablFishSimple is the simplest type of fish, wrapping a single * conversion function, (note this might not be the optimal chosen * conversion even if it exists) + * + * TODO: exterminate */ typedef struct { @@ -221,39 +222,35 @@ typedef struct /* BablFishPath is a combination of registered conversions, both - * from the reference types / model conversions, and optimized paths. + * from the reference types / model conversions, and optimized format to + * format conversion. * * This is the most advanced scheduled species of fish, some future - * version of babl might even be evovling combined fishes in a background - * thread, based on profiled usage. For this to work in a future version - * transmogrification between the fish classes would be used. + * version of babl might even be evovling path fishes in a background + * thread, based on the fish instrumentation. For this to work in a future + * version transmogrification between the fish classes would be used. */ typedef struct { BablFish fish; - double cost; - double loss; + double cost; /* number of ticks *10 + chain_length */ + double loss; /* error introduced */ + BablConversion *conversion[BABL_HARD_MAX_PATH_LENGTH]; int conversions; } BablFishPath; -/* BablFishReference on the double versions of conversions - * that are required to exist for maximum sanity. +/* BablFishReference * * A BablFishReference is not intended to be fast, thus the algorithm - * encoded can use a multi stage approach, where some of the stages could - * be completely removed for optimization reasons. - * - * This is not the intention of the "BablFishReference factory", it's - * implementation is meant to be kept as small as possible wrt logic. + * encoded can use a multi stage approach, based on the knowledge babl + * has encoded in the pixel formats. * * One of the contributions that would be welcome are new fish factories. * * TODO: - * * cache the looked up conversions, removing all overhead but the - * actual conversions. * * make optimal use of a single allocation containing enough space - * for the maximum amount of memory needed in to adjecant buffers + * for the maximum amount of memory needed in two adjecant buffers * at any time. */ typedef struct @@ -263,7 +260,7 @@ typedef struct typedef struct { - BablInstance instance; /* path to .so / .dll is stored in instance name */ + BablInstance instance; /* path to .so / .dll is stored in instance name */ void *dl_handle; void (*destroy) (void); } BablExtension; diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c index 23b2976..092ca6c 100644 --- a/babl/babl-fish-path.c +++ b/babl/babl-fish-path.c @@ -292,6 +292,7 @@ babl_fish_path (Babl *source, babl->fish.processings = 0; babl->fish.pixels = 0; + babl->fish.msecs = 0; babl->fish.error = 200000; babl->fish_path.cost = 200000; @@ -399,14 +400,18 @@ babl_fish_path_process (Babl *babl, void *destination, long n) { + long ret; + babl_assert (source); babl_assert (destination); - - return chain_process (babl->fish_path.conversion, - babl->fish_path.conversions, - source, - destination, - n); + + ret = chain_process (babl->fish_path.conversion, + babl->fish_path.conversions, + source, + destination, + n); + + return ret; } diff --git a/babl/babl-fish-stats.c b/babl/babl-fish-stats.c index b34b03c..e02e6d3 100644 --- a/babl/babl-fish-stats.c +++ b/babl/babl-fish-stats.c @@ -57,6 +57,7 @@ table_destination_each (Babl *babl, fprintf (output_file, "

path %s to %s

", source->instance.name, destination->instance.name); if (fish->fish.processings > 0) { + fprintf (output_file, "msecs:%li
", fish->fish.msecs); fprintf (output_file, "Processings:%i
", fish->fish.processings); fprintf (output_file, "Pixels:%li
", fish->fish.pixels); } @@ -95,6 +96,7 @@ table_destination_each (Babl *babl, if (fish->fish.processings > 0) { + fprintf (output_file, "msecs:%li
", fish->fish.msecs); fprintf (output_file, "Processings:%i
", fish->fish.processings); fprintf (output_file, "Pixels:%li
", fish->fish.pixels); } @@ -175,6 +177,42 @@ table_source_each (Babl *babl, return 0; } +static int +each_conv (Babl *babl, + void *data) +{ + double error, cost; + + if (BABL(babl->conversion.source)->class_type != BABL_FORMAT) + return 0; + + error = babl_conversion_error (&babl->conversion); + cost = babl_conversion_cost (&babl->conversion); + + if (error>0.01) + { + fprintf (output_file, "
%s
", babl->instance.name); + fprintf (output_file, "
"); + } + else + { + fprintf (output_file, "
%s
", babl->instance.name); + } + fprintf (output_file, "error: %f cost: %4.0f processings: %i pixels: %li", error, cost, + babl->conversion.processings, babl->conversion.pixels); + fprintf (output_file, "
"); + + return 0; +} + +static void +conversions () +{ + fprintf (output_file, "

Conversions

\n"); + babl_conversion_each (each_conv, NULL); + fprintf (output_file, "
\n"); +} + void babl_fish_stats (FILE *file) { @@ -303,6 +341,8 @@ babl_fish_stats (FILE *file) fprintf (output_file, "
\n"); + conversions (); + fprintf (output_file, "\n"); } diff --git a/babl/babl-internal.c b/babl/babl-internal.c index ae7bc26..73af012 100644 --- a/babl/babl-internal.c +++ b/babl/babl-internal.c @@ -97,9 +97,17 @@ babl_process (Babl *babl, babl->class_type == BABL_FISH_PATH || babl->class_type == BABL_FISH_SIMPLE) { + long ret; + long ticks = babl_ticks (); + ret = babl_fish_process (babl, source, destination, n); + + ticks -= babl_ticks(); + ticks *= -1; + + babl->fish.msecs += ticks; babl->fish.processings++; - babl->fish.pixels += n; - return babl_fish_process (babl, source, destination, n); + babl->fish.pixels += ret; + return ret; } babl_fatal ("eek"); diff --git a/babl/babl-introspect.c b/babl/babl-introspect.c index e61b474..67379de 100644 --- a/babl/babl-introspect.c +++ b/babl/babl-introspect.c @@ -165,9 +165,10 @@ conversion_introspect (Babl *babl) { babl_log ("\t\tprocessings:%i pixels:%li", babl->conversion.processings, babl->conversion.pixels); - babl_log ("\t\tcost: %i error: %f", - babl_conversion_cost (&babl->conversion), - babl_conversion_error (&babl->conversion)); + if (BABL(babl->conversion.source)->class_type == BABL_FORMAT) + { + babl_log ("\t\terror: %f", babl_conversion_error (&babl->conversion)); + } } static void diff --git a/babl/babl-util.c b/babl/babl-util.c index 63284fb..032ee60 100644 --- a/babl/babl-util.c +++ b/babl/babl-util.c @@ -82,7 +82,7 @@ babl_list_each (void **list, static struct timeval start_time; static struct timeval measure_time; -#define msecs(time) ((time.tv_sec-start_time.tv_sec)*1000 + time.tv_usec/1000) +#define msecs(time) ((time.tv_sec-start_time.tv_sec)*10000000 + time.tv_usec) static void init_ticks (void) diff --git a/extensions/gggl.c b/extensions/gggl.c index b5dc30d..e26ab72 100644 --- a/extensions/gggl.c +++ b/extensions/gggl.c @@ -687,7 +687,7 @@ conv_gF_gaF (unsigned char *src, unsigned char *dst, long samples) long n=samples; while (n--) { - *(int *) dst = (*(int *) src); + *(float *) dst = (*(float *) src); dst += 4; src += 4; *(float *) dst = 1.0; @@ -714,7 +714,7 @@ conv_gF_rgbF (unsigned char *src, unsigned char *dst, long samples) for (c = 0; c < 3; c++) { - (*(int *) dst) = (*(int *) src); + (*(float *) dst) = (*(float *) src); dst += 4; } src += 4; @@ -736,7 +736,7 @@ conv_rgbF_gF (unsigned char *src, unsigned char *dst, long samples) sum += (*(float *) src); src += 4; } - sum /= 3; + sum /= 3.0; (*(float *) dst) = sum; dst += 4; } @@ -869,7 +869,13 @@ conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples) for (c = 0; c < 3; c++) { - *(unsigned char *) dst = rint ((*(float *) src) * 255.0); + int val=rint ((*(float *) src) * 255.0); + if (val<0) + *(unsigned char *) dst = 0; + else if (val>255) + *(unsigned char *) dst = 255; + else + *(unsigned char *) dst = val; dst += 1; src += 4; } -- 2.30.2